#ifndef __COMMDEF_H__
#define __COMMDEF_H__

#include <stdint.h>
#include <memory>
#include "plat/nonecopyable.h"
#include "os/semaphore.h"
#include "soc/soc_misc.h"

//协议等待Resp超时
#define COMM_WAIT_TIMEOUT_DEFAULT 1500

//协议MESSAGE
class IProtocolMessage : public NoneCopyable
{
public:
    explicit IProtocolMessage()
    {
        AutoId ++;
    }
    virtual ~IProtocolMessage(){}

public:
    template<typename T>
    T* As()
    {
        return static_cast<T*>(this);
    }

public:
    uint32_t AutoId = 0; //调试使用
};

//协议接口
class IProtocol : public NoneCopyable
{
public:
    explicit IProtocol(){}
    virtual ~IProtocol(){}

public:
    //打包
    virtual int Packet(std::shared_ptr<IProtocolMessage> msg) = 0;
    //获取最后的打包buffer
    virtual uint8_t *GetSendBuffer() = 0;
    //因为嵌入式速度有限，采用字节方式解析
    virtual std::shared_ptr<IProtocolMessage> Parse(uint8_t b) = 0;
    //复位解析器
    virtual void Reset() = 0;

    //是否应答 [暂不设计]
    virtual bool IsAck(std::shared_ptr<IProtocolMessage> sendMsg, std::shared_ptr<IProtocolMessage> recvMsg) = 0;
    //是否响应
    virtual bool IsResponse(std::shared_ptr<IProtocolMessage> sendMsg, std::shared_ptr<IProtocolMessage> recvMsg) = 0;
};

class WaitObject : public NoneCopyable
{
public:
    explicit WaitObject(){}
    explicit WaitObject(IProtocol *protocol, std::shared_ptr<IProtocolMessage> msg)
    {
        m_protocol = protocol;
        m_sendMsg = msg;
    }

    virtual ~WaitObject(){}

public:
    //通知消息，判断超时
    bool TryNotify(std::shared_ptr<IProtocolMessage> msg);

    inline bool Wait(int timeout)
    {
        return m_sem.Acquire(timeout);
    }

    inline std::shared_ptr<IProtocolMessage> GetRecvMessage()
    {
        return m_recvMsg;
    }

private:
    IProtocol *m_protocol = nullptr;
    std::shared_ptr<IProtocolMessage> m_sendMsg = nullptr;
    
    bool m_isNotify = false;
    std::shared_ptr<IProtocolMessage> m_recvMsg = nullptr;
    Semaphore m_sem{0, 1};
};

#endif // __COMMDEF_H__
